package com.mellarius.activities;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Scanner;

import com.helper.BdHelper;
import com.helper.FilesHelper;
import com.mellarius.R;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

public class Synchronize extends Activity implements OnClickListener {

	FileOutputStream fos = null;
	BufferedOutputStream bos = null;
	public final static int FILE_SIZE = 13158176;
	public static final String TAG = "Connection";
	public static final int TIMEOUT = 10;
	private String connectionStatus = null;
	private String socketData = null;
	private Handler mHandler = null;
	ServerSocket server = null;
	FileInputStream fis = null;
	BufferedInputStream bis = null;
	DataOutputStream os = null;
	DataInputStream is = null;
	BdHelper bdHelper;
	private static String FILE_TO_RECEIVED;
	private static String DB_NAME = "mellariusBd.db3";
	Context c;
	Intent i = null;
	TextView tv = null;
	TextView ip = null;
	FilesHelper filesHelper;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		c = this;
		this.filesHelper =new FilesHelper(c);
		Intent intent = getIntent();
		FILE_TO_RECEIVED = this.getDatabasePath(DB_NAME).getAbsolutePath();
		setContentView(R.layout.activity_sync);
		// Set up click listeners for the buttons
		View connectButton = findViewById(R.id.connect_button);
		connectButton.setOnClickListener(this);
		View onBtn = findViewById(R.id.hdmi_on);
		ip = (TextView) findViewById(R.id.iptext);
		onBtn.setOnClickListener(this);
		ip.setText(intent.getStringExtra(GestorActividade.EXTRA_IP));
		// i = new Intent(this, Connected.class);
		mHandler = new Handler();
	}

	public void onClick(View v) {

		// initialize server socket in a new separate thread
		new Thread(initializeConnection).start();
		filesHelper.setLastIp(ip.getText().toString());
		String msg = "Attempting to connect...";
		Toast.makeText(this, msg, msg.length()).show();
	}

	private Runnable initializeConnection = new Thread() {
		public void run() {

			Socket client = null;
			// initialize server socket
			try {
				if(GestorActividade.getWifi()){
					client = new Socket(ip.getText().toString(),38300);
					
				}else{
					server = new ServerSocket(38300);
					server.setSoTimeout(TIMEOUT * 38300);
					// attempt to accept a connection
					client = server.accept();
					if (client != null) {
						Globals.connected = true;
						// print out success
						connectionStatus = "Connection was succesful!";
						Log.d(TAG, "connected!");
						mHandler.post(showConnectionStatus);
						while (Globals.scannerIn.hasNext()) {
							socketData = Globals.scannerIn.next();
							mHandler.post(socketStatus);

						}
						// startActivity(i);
					}
					
				}
				Globals.scannerIn = new Scanner(client.getInputStream());
				Globals.socketOut = new DataOutputStream(client.getOutputStream());
				Globals.socketIn = new DataInputStream(client.getInputStream());
				if (bdHelper.checkDataBase(c)) {
					syncdDataBase();

				} else {
					getDataBase();
				}

				// Globals.socketIn.
			} catch (SocketTimeoutException e) {
				// print out TIMEOUT
				connectionStatus = "Connection has timed out! Please try again";
				mHandler.post(showConnectionStatus);
			} catch (IOException e) {
				Log.e(TAG, "" + e);
			} finally {
				// close the server socket
				try {
					if (server != null)
						server.close();
				} catch (IOException ec) {
					Log.e(TAG, "Cannot close server socket" + ec);
				}
			}
		}
	};

	public void syncdDataBase() throws IOException {

		File myFile = new File(getDatabasePath(Globals.FILE_TO_SEND).getPath());
		byte[] mybytearray = new byte[(int) myFile.length()];
		byte[] buffer = new byte[1024];
		os = Globals.socketOut;

		// Send first message
		os.writeChars("G");
		os.writeUTF("This is the first type of message.");
		os.flush(); // Send off the data

		fis = new FileInputStream(myFile);
		bis = new BufferedInputStream(fis);
		int length;
		os.writeInt((int) myFile.length());
		while ((length = bis.read(buffer)) > 0) {
			os.write(buffer, 0, length);
		}
		System.out.println("Sending " + Globals.FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
		os.flush();
		inputFile();

		if (bis != null)
			bis.close();
		if (fis != null)
			fis.close();
		if (os != null)
			;
		os.close();
		Globals.socketIn.close();
	}

	public void getDataBase() throws IOException {

		os = Globals.socketOut;
		// Send first message
		os.writeChars("O");
		os.writeUTF("This is the first type of message.");
		os.flush(); // Send off the data
		inputFile();
		os.close();
		Globals.socketIn.close();

	}

	private void inputFile() {

		is = Globals.socketIn;
		int bytesRead;
		try {
			fos = new FileOutputStream(FILE_TO_RECEIVED);

			bos = new BufferedOutputStream(fos);

			bytesRead = is.readInt();
			byte[] mybytearray = new byte[bytesRead];
			is.readFully(mybytearray);
			bos.write(mybytearray, 0, bytesRead);
			bos.flush();
			if (fos != null) {
				fos.close();
			}
			if (bos != null) {
				bos.close();
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Pops up a "toast" to indicate the connection status
	 */
	private Runnable showConnectionStatus = new Runnable() {
		public void run() {
			Toast.makeText(getBaseContext(), connectionStatus, Toast.LENGTH_SHORT).show();
		}
	};

	private Runnable socketStatus = new Runnable() {

		public void run() {

			tv.setText(socketData);
		}
	};

	public static class Globals {
		public static final String FILE_TO_SEND = "mellariusBd.db3";
		public static boolean connected;
		public static Scanner scannerIn;
		public static DataInputStream socketIn;
		public static DataOutputStream socketOut;
		public static DataInputStream socket2In;
		public static DataOutputStream socket2Out;
	}

}
